// 引入 axios 库
import axios from 'axios'
// 引入弹窗
import { Message } from 'element-ui'

import { getTimeStamp } from '@/utils/auth'

// 引入 vuex
import store from '@/store'

// 引入路由
import router from '@/router'

const TimeOutDuration = 2000

// 创建实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000
})

// 请求拦截器 在每个请求 headers 带上 token (如果请求本身没有带, 但是数据中有 token)
service.interceptors.request.use(config => {
  // 如果请求本身没有带上 token 但是 vuex 里面存在, 就应该默认注入
  if (!config.headers.Authorization && store.getters.token) {
    // 在注入之前, 先判断一下是否已经过期
    if (!isTimeOut()) {
      // 这里是 JWT 鉴权标准的 Bearer Token 规范
      // 格式是: 'Bearer xxxxxx'
      config.headers.Authorization = `Bearer ${store.getters.token}`
    } else {
      // 这里是已经过期的状况
      // 登出操作删除数据
      store.dispatch('user/logout')
      // 跳回登录页
      router.push('/login?redirect=' + location.hash.substring(1))
      // return Promise.reject 停止请求
      return Promise.reject(new Error('登录已过期'))
    }
  }

  return config
}, err => {
  // 防御性编程, 处理可能出现的报错
  Message.error(err.message)
  return Promise.reject(new Error(err.message))
})

// 响应拦截器
service.interceptors.response.use(res => {
  // 处理网络层面的成功
  const { message, success, data } = res.data
  if (success) {
    // 数据层面的成功
    return data
  } else {
    // 数据层面的失败
    Message.error(message)
    return Promise.reject(new Error(message))
  }
}, err => {
  // 处理网络层面的失败
  // 这里是网络层面的失败, 以前都是用来处理断网, 写错url 之类
  // 现在多了一种可能性, 就是 token 失效
  // 这里就应该做判断, 如果是 code === 10002
  if (err.response && err.response.data && err.response.data.code === 10002) {
    // 退出
    // 做登出和跳转操作
    store.dispatch('user/logout')
    router.push('/login?redirect=' + location.hash.substring(1))
  } else {
    // 其他的处理
    console.dir(err)
    Message.error(err.message)
  }

  return Promise.reject(new Error(err.message))
})
// service.interceptors.response.use(
//   // 响应拦截器, 可以接受两个函数所谓回调参数
//   // 第一个处理成功, 第二个处理失败
//   res => {
//     // 处理成功逻辑
//     const { success, message, data } = res.data
//     if (success) {
//       // 直接返回数据
//       return data
//     } else {
//       // 失败以后弹出提示然后停止这个请求
//       Message.error(message)
//       // 不能直接返回数据, 因为请求会以为成功
//       // 需要返回一个拒绝的 Promise 走 catch 流程
//       return Promise.reject(new Error(message))
//     }
//     // return res
//   }, err => {
//     // 处理失败逻辑
//     console.log('拦截器失败逻辑')
//     console.dir(err)

//     Message.error(err.message)
//     return Promise.reject(new Error(err.message))
//   }
// )

function isTimeOut() {
  const currentTime = Date.now()
  const timeStamp = getTimeStamp()
  return (currentTime - timeStamp) / 1000 > TimeOutDuration
}

export default service
